package im.xz.cn.xiareviewer;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;

public class chat implements Listener {
    Plugin plugin = XiaReviewer.getPlugin(XiaReviewer.class);

    String BASE_URL = plugin.getConfig().getString("apiUrl");
    String API_KEY = plugin.getConfig().getString("apiKey");
    String PromptSystem = plugin.getConfig().getString("promptSystem");
    String model = plugin.getConfig().getString("model");
    int timeout = (plugin.getConfig().getInt("timeout")) * 1000;
    List<String> whiteList = plugin.getConfig().getStringList("whiteList");
    final ConcurrentHashMap<String, Boolean> playerRequestStatus = new ConcurrentHashMap<>();
    private boolean startRequestFor(Player player) {
        String playerName = player.getName();
        if (playerRequestStatus.containsKey(playerName) && playerRequestStatus.get(playerName)) {
            return false;
        } else {
            playerRequestStatus.put(playerName, true);
            new Timer().schedule(new TimerTask() {
                @Override
                public void run() {
                    playerRequestStatus.remove(playerName);
                }
            }, timeout);
            return true;
        }
    }
    @EventHandler
    public void chatEvent(AsyncPlayerChatEvent event){
        Player player = event.getPlayer();
        String message = event.getMessage();
        String playerName = player.getName();
        if (!isPlayerWhitelisted(playerName)) {
            if (!startRequestFor(player)) {
                player.sendMessage("§bGemini §f| §c前条消息审核中");
                System.out.println(playerName + "发送了预处理消息,但因为他已有消息正在处理中,所以此条被抛弃: " + message);
                event.setCancelled(true);
            } else {
                event.setCancelled(true);
                System.out.println(playerName + "发送了预处理消息: " + message);
                handleAIRequest(player, message);
            }
        }
    }
    private void handleAIRequest(Player player, String message) {
        CompletableFuture.runAsync(() -> {
            try {
                URL url = new URL(BASE_URL);
                String name = player.getName();
                HttpURLConnection conn = getHttpURLConnection(message, url);

                int responseCode = conn.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) {
                    JsonNode rootNode = getJsonNode(conn);
                    JsonNode choicesNode = rootNode.path("choices").get(0);
                    JsonNode messageNode = choicesNode.path("message");

                    if (messageNode.has("content") && !messageNode.get("content").isNull()) {
                        String content = messageNode.get("content").asText();
                        String[] parts = content.split(";");
                        boolean legal = false;
                        boolean help = false;
                        String fix = "<xiaDefault>";
                        for (String part : parts) {
                            part = part.trim();
                            if (part.startsWith("legal=")) {
                                legal = part.substring("legal=".length()).equals("true");
                            } else if (part.startsWith("help=")) {
                                help = part.substring("help=".length()).equals("true");
                            } else if (part.startsWith("fix:")) {
                                fix = part.substring("fix:".length());
                            }
                        }

                        boolean finalLegal = legal;
                        boolean finalHelp = help;
                        String finalFix = fix;
                        Bukkit.getScheduler().runTask(plugin, () -> {
                            if (finalLegal) {
                                Bukkit.broadcastMessage("<" + player.getName() + "> " + message);
                            } else {
                                player.sendMessage("§bGemini §f| §c您的消息包含违规内容，已被修正。");
                                Bukkit.broadcastMessage("<" + player.getName() + "> " + finalFix);

                                if (finalHelp) {
                                    player.sendMessage("§b§l—— Gemini ——");
                                    player.sendMessage("§2§n    你不孤单，我们都在。");
                                    player.sendMessage("§v§o如果需要帮助,请拨打全国24小时免费心理咨询热线");
                                    player.sendMessage("全国24小时免费心理咨询：010-82951332");
                                    player.sendMessage("§b§l—— Gemini ——");
                                }
                            }
                        });
                        System.out.println("返回" + name + ": " + content);
                    } else {
                        player.sendMessage("§bGemini §f| §c内容字段缺失或为空");
                    }
                } else {
                    Bukkit.getScheduler().runTask(plugin, () -> {
                        try {
                            player.sendMessage("§bGemini §f| §c审核失败，错误码：" + conn.getResponseCode());
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                    });
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                playerRequestStatus.remove(player.getName());
            }
        });
    }
    private @NotNull HttpURLConnection getHttpURLConnection(String message, URL url) throws IOException {
        String jsonInputString = "{"
                + "\"model\": \"" + model +"\", "
                + "\"messages\": ["
                + "    {\"role\": \"system\", \"content\": \"" + PromptSystem +"\"}, "
                + "    {\"role\": \"user\", \"content\": \"" + message + "\"}"
                + "], "
                + "\"stream\": false"
                + "}";
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setDoOutput(true);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/json");
        conn.setRequestProperty("Authorization", "Bearer " + API_KEY);
        try (OutputStream os = conn.getOutputStream()) {
            byte[] input = jsonInputString.getBytes(StandardCharsets.UTF_8);
            os.write(input, 0, input.length);
        }
        return conn;
    }
    private static JsonNode getJsonNode(HttpURLConnection conn) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(
                conn.getInputStream(), StandardCharsets.UTF_8));
        String inputLine;
        StringBuilder response = new StringBuilder();

        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();
        ObjectMapper objectMapper = new ObjectMapper();
        return objectMapper.readTree(response.toString());
    }
    private boolean isPlayerWhitelisted(String playerName) {
        return whiteList.contains(playerName);
    }
}